﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.ComponentModel;
using System.Diagnostics;

using System.Xml.Serialization;

#if (LINQ)
using System.Data.Linq;
using System.Linq;
#endif

using System.Runtime.Serialization;

using Robin.LightNing.Interfaces;
using Robin.LightNing.DynamicQuery;

namespace Robin.LightNing.Core
{
    /// <summary>
    /// rbEntityCollection是 <see cref="rbEntity"/> 对象的集合. rbEntityCollection代表数据库中的一条或多条数据.
    /// 每条数据代表一个集合中的rbEntity对象.
    /// </summary>
    /// <remarks>
    /// 下面的代码演示了如何从数据库中加载所有的数据，并且按salary进行降序排序.
    /// <code>
    /// EmployeesCollection coll = new EmployeesCollection();
    /// coll.Query.OrderBy(coll.Query.Salary.Descending);
    /// if(coll.Query.Load())
    /// {
    ///		foreach(Employees emp in coll)
    ///		{
    ///			// 执行自定义语句
    ///		}
    ///  
    /// 	// 添加一条数据并保存
    /// 	Employees newEmp = coll.AddNew();
    /// 	newEmp.FirstName = "James";
    /// 	newEmp.LastName  = "Murphy";
    /// 	
    /// 	// 保存
    /// 	coll.Save();
    /// }
    /// </code>
    /// </remarks>
#if (!WindowsCE)
    [DefaultProperty("Indexer")]
    [CollectionDataContract]
#endif
    [Serializable]
    public abstract partial class rbEntityCollection<T> : rbEntityCollectionBase, ICommittable
        where T : rbEntity, new()
    {
        public rbEntityCollection()
        {
            entities.RaiseListChangedEvents = false;
            this.entities.ListChanged += new ListChangedEventHandler(this.OnListChanged);
        }

        /// <summary>
        /// 内部调试的时候调用,允许你在调试的时候可以轻松的查看集合.
        /// </summary>
#if (!WindowsCE)
        [DebuggerBrowsable(DebuggerBrowsableState.RootHidden | DebuggerBrowsableState.Never)]
        [Browsable(false)]
#endif
        virtual protected BindingList<T> Debug
        {
            get
            {
                return this.entities;
             }
        }

        #region Overridden Methods

        /// <summary>
        /// 集合创建实体的时候调用
        /// </summary>
        /// <returns></returns>
        protected override rbEntity CreateEntity()
        {
            return new T();
        }

        internal override IList GetList()
        {
            return entities as IList;
        }

        internal override IEnumerable GetDeletedEntities()
        {
            return this.deletedEntities as IEnumerable;
        }

        internal override IEnumerable GetEntities()
        {
            return this.entities;
        }

        internal override void AddEntityToDeletedList(rbEntity entity)
        {
            if (entity.rowState == rbDataRowState.Modified || entity.rowState == rbDataRowState.Unchanged)
            {
                if (deletedEntities == null)
                {
                    deletedEntities = new List<T>();
                }

                T obj = (T)entity;
                deletedEntities.Add(obj);
            }

            if (entitiesFilterBackup != null && entitiesFilterBackup.Contains((T)entity))
            {
                entitiesFilterBackup.Remove((T)entity);
                OnUpdateViewNotification(this, ListChangedType.ItemDeleted, entity);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override Type GetEntityType()
        {
            return typeof(T);
        }

        #endregion


        /// <summary>
        /// 添加实体到集合中
        /// </summary>
        /// <returns>新建的实体</returns>
        virtual public T AddNew()
        {
            IBindingList list = this as IBindingList;

            T entity = (T)list.AddNew();

            if (fks != null)
            {
                foreach (string column in fks.Keys)
                {
                    entity.SetColumn(column, fks[column]);
                }
            }

            return entity;
        }

        /// <summary>
        /// 创建集合的副本
        /// </summary>
        /// <typeparam name="C"></typeparam>
        /// <returns>The newly created collection</returns>
        virtual public C Clone<C>() where C : rbEntityCollection<T>, new()
        {
            C collection = new C();

            foreach (T entity in entities)
            {
                T newEntity = entity.Clone<T>();
                collection.Add(newEntity);
            }

            return collection;
        }

        public override void CombineDeletedEntities()
        {
            if (this.deletedEntities != null && this.deletedEntities.Count > 0)
            {
                foreach (T entity in deletedEntities)
                {
                    entities.Add(entity);
                }
            }
        }

        public override void SeparateDeletedEntities()
        {
            foreach (T entity in this.entities)
            {
                if (entity.rowState == rbDataRowState.Deleted)
                {
                    if (deletedEntities == null)
                    {
                        deletedEntities = new BindingList<T>();
                    }

                    deletedEntities.Add(entity);
                }
            }

            if (this.deletedEntities != null && this.deletedEntities.Count > 0)
            {
                foreach (T entity in deletedEntities)
                {
                    entities.Remove(entity);
                }
            }
        }

        /// <summary>
        /// 合并两个集合到一个单一集合中
        /// </summary>
        /// <remarks>
        /// 执行完之后，传递的集合不再有效，不能使用或重新加载.
        /// </remarks>
        /// <example>
        /// 下面的例子展示了把表的第一行和后三行数据合并到单个集合中.
        /// <code>
        /// EmployeesCollection dest = new EmployeesCollection();
        /// dest.Query.rb.Top = 3;
        /// dest.Query.OrderBy(dest.Query.EmployeeID, rbOrderByDirection.Ascending);
        /// dest.Query.Load();
        /// 
        /// EmployeesCollection src = new EmployeesCollection();
        /// src.Query.rb.Top = 3;
        /// src.Query.OrderBy(src.Query.EmployeeID, rbOrderByDirection.Descending);
        /// src.Query.Load();
        ///
        /// dest.Combine(src);
        /// </code>
        /// </example>
        /// <param name="collectionToAdd">被合并的集合, 调用完后变为空的</param>
        virtual public void Combine(rbEntityCollection<T> collectionToAdd)
        {
            RaiseListChangeEvents_Disable();

            foreach (rbEntity entity in collectionToAdd.entities)
            {
                entity.Collection = this;

                if (this.fks != null)
                {
                    foreach (string col in this.fks.Keys)
                    {
                        entity.currentValues[col] = this.fks[col];
                    }
                }

                // This entity now takes on the Collection's Connection info
                entity.rb.Connection.Name = this.rb.Connection.Name;

#if (!WindowsCE)
                if (entitiesFilterBackup != null)
                {
                    entitiesFilterBackup.Add((T)entity);
                }
                else
                {
#endif
                    entities.Add((T)entity);
#if (!WindowsCE)
                }
#endif
            }

#if (!WindowsCE)
            if (currentFilter != null)
            {
                this.Filter = currentFilter;
            }
#endif

            collectionToAdd.entities.Clear();
            collectionToAdd.rb.Connection = null;

            RaiseListChangeEvents_Restore();

            OnUpdateViewNotification(this, ListChangedType.Reset, null);

            if (entities.RaiseListChangedEvents)
            {
                this.OnListChanged(this, new ListChangedEventArgs(ListChangedType.Reset, -1));
            }
        }
        /// <summary>
        /// 标记为已删除
        /// </summary>
        public override void MarkAllAsDeleted()
        {
            RaiseListChangeEvents_Disable();

            if (deletedEntities == null)
            {
                deletedEntities = new List<T>();
            }

            foreach (T e in entities)
            {
                if (e.RowState != rbDataRowState.Added)
                {
                    deletedEntities.Add(e);
                    e.rowState = rbDataRowState.Deleted;
                }

                if (entitiesFilterBackup != null)
                {
                    entitiesFilterBackup.Remove(e);
                }
            }

            this.entities.Clear();

            RaiseListChangeEvents_Restore();

            OnUpdateViewNotification(this, ListChangedType.Reset, null);

            if (entities.RaiseListChangedEvents)
            {
                this.OnListChanged(this, new ListChangedEventArgs(ListChangedType.Reset, -1));
            }
        }

        /// <summary>
        /// 集合查询记载完毕的时候调用
        /// </summary>
        /// <param name="query">刚加载的查询</param>
        /// <param name="table">返回的DataTable</param>
        /// <returns>至少返回一条数据，返回true</returns>
        protected bool OnQueryLoaded(rbDynamicQuery query, DataTable table)
        {
            this.PopulateCollection(table);

            // Add ourself into the list with a map name of string.Empty
            Dictionary<string, Dictionary<object, rbEntityCollectionBase>> collections = new Dictionary<string, Dictionary<object, rbEntityCollectionBase>>();
            Dictionary<object, rbEntityCollectionBase> me = new Dictionary<object, rbEntityCollectionBase>();
            me[string.Empty] = this;
            collections[string.Empty] = me;

            if (query.rb2.PrefetchMaps != null)
            {
                foreach (rbPrefetchMap map in query.rb2.PrefetchMaps)
                {
                    DataTable preFetchedTable = map.Table;

                    Dictionary<object, rbEntityCollectionBase> loadedCollections = null;

                    if (map.Path == string.Empty)
                    {
                        loadedCollections = collections[string.Empty];
                    }
                    else
                    {
                        loadedCollections = collections[map.Path];
                    }

                    Dictionary<object, rbEntityCollectionBase> newCollection = new Dictionary<object, rbEntityCollectionBase>();
                    foreach (rbEntityCollectionBase collection in loadedCollections.Values)
                    {
                        foreach (rbEntity obj in collection)
                        {
                            obj.rb.IsLazyLoadDisabled = true;

                            object key = null;

                            // Avoid doing the Split() if we can
                            if (map.IsMultiPartKey)
                            {
                                key = string.Empty;

                                string[] columns = map.ParentColumnName.Split(',');
                                foreach (string col in columns)
                                {
                                    key += Convert.ToString(obj.GetColumn(col));
                                }
                            }
                            else
                            {
                                key = obj.GetColumn(map.ParentColumnName);
                            }

                            IEntity iEntity = obj as IEntity;
                            newCollection[key] = iEntity.CreateCollection(map.PropertyName);
                        }
                    }

                    Dictionary<string, int> ordinals = null;
                    DataRowCollection rows = preFetchedTable.Rows;
                    int count = rows.Count;
                    for (int i = 0; i < count; i++)
                    {
                        DataRow row = rows[i];

                        object key = null;

                        // Avoid doing the Split() if we can
                        if (map.IsMultiPartKey)
                        {
                            key = string.Empty;

                            string[] columns = map.MyColumnName.Split(',');
                            foreach (string col in columns)
                            {
                                key += Convert.ToString(row[col]);
                            }
                        }
                        else
                        {
                            key = row[map.MyColumnName];
                        }

                        rbEntityCollectionBase c = newCollection[key];

                        IEntityCollection iColl = c as IEntityCollection;
                        ordinals = iColl.PopulateCollection(row, ordinals);
                    }

                    collections[map.PropertyName] = newCollection;
                }
            }

            return (this.Count > 0) ? true : false;
        }

        #region Filter
#if (!WindowsCE)
        /// <summary>
        /// 使用LINQ表达式过滤集合
        /// </summary>
        /// <remarks>
        /// 下面的代码展示了如何过滤和排序.单独的和一起的,要清除过滤，只需要将该属性设置为'null' 或 'Nothing'
        /// <code>
        /// // 根据Employee’s first name排序
        /// coll.Filter = coll.AsQueryable().OrderByDescending(d => d.FirstName);
        /// 
        /// //过滤出所有缺少FirstName的
        /// coll.Filter = coll.AsQueryable().Where(d => d.FirstName == null);
        /// 
        /// // 既过滤又排序
        /// coll.Filter = coll.AsQueryable().Where(d => d.FirstName == null).OrderByDescending(d => d.LastName);
        /// </code>
        /// </remarks>    
#if (!WindowsCE)        
        [Browsable(false)]
#endif
        public IQueryable<T> Filter
        {
            get
            {
                return currentFilter;
            }

            set
            {
                RemoveFilter();

                if (value != null)
                {
                    ApplyFilter(value);
                }
                currentFilter = value;

                if (entities.RaiseListChangedEvents)
                {
                    OnListChanged(this, new ListChangedEventArgs(ListChangedType.Reset, -1));
                }
            }
        }

        /// <summary>
        /// 如果当前集合是通过Filter属性过滤过的，返回true
        /// </summary>
#if (!WindowsCE)
        [Browsable(false)]
#endif
        public bool HasFilter
        {
            get
            {
                return currentFilter != null ? true : false;
            }
        }

        private void RemoveFilter()
        {
            currentFilter = null;

            if (entitiesFilterBackup == null) return;

            RaiseListChangeEvents_Disable();
            entities.Clear();

            foreach (T obj in entitiesFilterBackup)
            {
                entities.Add(obj);
            }
            entitiesFilterBackup = null;

            RaiseListChangeEvents_Restore();
        }

        private void ApplyFilter(IQueryable<T> filter)
        {
            BindingList<T> temp = new BindingList<T>();

            foreach (T obj in entities)
            {
                temp.Add(obj);
            }

            RaiseListChangeEvents_Disable();

            List<T> list = filter.ToList<T>();
            entities.Clear();
            foreach (T obj in list)
            {
                entities.Add(obj);
            }

            entitiesFilterBackup = temp;

            RaiseListChangeEvents_Restore();
        }
#else
        /// <summary>
        /// 如果当前集合是通过Filter属性过滤过的，返回true
        /// </summary>
        public bool HasFilter
        {
            get
            {
                return false;
            }
        }
#endif
        #endregion

        /// <summary>
        /// 集合中实体的数量
        /// </summary>
#if (!WindowsCE)
        [Browsable(false)]
#endif
        public override int Count
        {
            get
            {
                return entities.Count;
            }
        }

        /// <summary>
        /// 如果集合已加载数据，并且加载的数据只要有一行没有被标记为Deleted,返回true
        /// </summary>
        virtual public bool HasData
        {
            get
            {
                return entities.Count > 0 ? true : false;
            }
        }

        /// <summary>
        /// 如果调用AddNew(), MarkAsDeleted(),或任何实体表的基础属性发生改变,设置为true.
        /// 成功调用<see cref="Save"/> 之后，返回 false.
        /// </summary>
        public override bool IsDirty
        {
            get
            {
                if (entities.Count > 0)
                {
                    foreach(rbEntity entity in entities)
                    {
                        switch (entity.RowState)
                        {
                            case rbDataRowState.Added:
                                return true;
                            case rbDataRowState.Modified:
                                return true;
                            case rbDataRowState.Deleted:
                                return true;
                        }
                    }
                }

                if (deletedEntities != null && deletedEntities.Count > 0)
                {
                    return true;
                }

                return false;
            }
        }

        /// <summary>
        /// 集合的索引.首选使用foreach()语法，更快速.
        /// </summary>
        /// <param name="index">所需的实体索引从0开始</param>
        /// <returns>实体</returns>
#if (!WindowsCE)
        [DebuggerBrowsable(DebuggerBrowsableState.Collapsed)]
#endif
        public T this[int index]
        {
            get
            {
                return entities[index];
            }
            set
            {
                entities[index] = value;
            }
        }

        #region RaiseListChangedEvents Processing

        [NonSerialized]
        private bool raiseListChangedEvents = false;
        /// <summary>
        /// 
        /// </summary>
        public void RaiseListChangeEvents_Disable()
        {
            raiseListChangedEvents = entities.RaiseListChangedEvents;
            entities.RaiseListChangedEvents = false;
        }
        /// <summary>
        /// 
        /// </summary>
        public void RaiseListChangeEvents_Restore()
        {
            entities.RaiseListChangedEvents = raiseListChangedEvents;
        }
        /// <summary>
        /// 
        /// </summary>
        public bool RaiseListChangeEventsEnabled
        {
            get
            {
                return entities.RaiseListChangedEvents;
            }
        }

        #endregion

        /// <summary>
        /// 集合加载的时候调用，并且负责把ADO.NET DataTable转换到集合中
        /// </summary>
        /// <param name="table">需要被加载的DataTable</param>
        protected void PopulateCollection(DataTable table)
        {
            RaiseListChangeEvents_Disable();

            try
            {
                this.entities.Clear();

                // Now let's actually create an rbEntity for each DataRow and thereby populate
                // the collection
                string columnName;
                rbColumnMetadataCollection esCols = Meta.Columns;
                rbColumnMetadata esCol;
                DataRow row;
                DataColumnCollection cols = table.Columns;
                DataRowCollection rows = table.Rows;
                int rowCount = rows.Count;
                int colCount = cols.Count;

                Dictionary<string, int> ordinals = new Dictionary<string, int>(colCount);

                for(int c = 0; c < colCount; c++)
                {
                    DataColumn col = cols[c];

                    // Let's make sure we use the Case in the Metadata Class, if they return "employeeid" in a proc
                    // this little trick will make sure we use "EmployeeId" for our property accessors
                    esCol = esCols.FindByColumnName(col.ColumnName);
                    columnName = esCol != null ? esCol.Name : col.ColumnName;

                    ordinals[columnName] = col.Ordinal;

                    if (selectedColumns == null)
                    {
                        selectedColumns = new Dictionary<string, int>(cols.Count);
                    }

                    if (esCol != null)
                    {
                        selectedColumns[columnName] = c;
                    }

                    if (esCol == null)
                    {
                        if (extraColumnMetadata == null)
                        {
                            extraColumnMetadata = new Dictionary<string, rbColumnMetadata>(cols.Count);
                        }

                        extraColumnMetadata[columnName] = new rbColumnMetadata(columnName, c, col.DataType);
                    }
                }

                bool isLazyLoadDisabled = this.rb.IsLazyLoadDisabled;
                for (int i = 0; i < rowCount; i++)
                {
                    T obj = AddNew();
                    obj.rb.IsLazyLoadDisabled = isLazyLoadDisabled;

                    row = rows[i];

                    object[] values = row.ItemArray;

                    obj.currentValues = new rbSmartDictionary(ordinals, values);
                    obj.originalValues = new rbSmartDictionary(ordinals, values, true);
                    if (obj.m_modifiedColumns != null) obj.m_modifiedColumns = null;
                    obj.rowState = rbDataRowState.Unchanged;
                }
            }
            finally
            {
                RaiseListChangeEvents_Restore();
                OnUpdateViewNotification(this, ListChangedType.Reset, null);

                if (entities.RaiseListChangedEvents)
                {
                    OnListChanged(this, new ListChangedEventArgs(ListChangedType.Reset, -1));
                }
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="row"></param>
        /// <param name="ordinals"></param>
        /// <returns></returns>
        protected override Dictionary<string, int> PopulateCollectionPrefetch(DataRow row, Dictionary<string, int> ordinals)
        {
            #region Column Metadata
            if (this.selectedColumns == null)
            {
                // Now let's actually create an rbEntity for each DataRow and thereby populate
                // the collection
                string columnName;
                rbColumnMetadataCollection esCols = Meta.Columns;
                rbColumnMetadata esCol;
                DataColumnCollection cols = row.Table.Columns;
                DataRowCollection rows = row.Table.Rows;
                int rowCount = rows.Count;
                int colCount = cols.Count;

                ordinals = new Dictionary<string, int>(colCount);

                for (int c = 0; c < colCount; c++)
                {
                    DataColumn col = cols[c];

                    // Let's make sure we use the Case in the Metadata Class, if they return "employeeid" in a proc
                    // this little trick will make sure we use "EmployeeId" for our property accessors
                    esCol = esCols.FindByColumnName(col.ColumnName);
                    columnName = esCol != null ? esCol.Name : col.ColumnName;

                    ordinals[columnName] = col.Ordinal;

                    if (selectedColumns == null)
                    {
                        selectedColumns = new Dictionary<string, int>(cols.Count);
                    }

                    if (esCol != null)
                    {
                        selectedColumns[columnName] = c;
                    }

                    if (esCol == null)
                    {
                        if (extraColumnMetadata == null)
                        {
                            extraColumnMetadata = new Dictionary<string, rbColumnMetadata>(cols.Count);
                        }

                        extraColumnMetadata[columnName] = new rbColumnMetadata(columnName, c, col.DataType);
                    }
                }
            }
            #endregion

            T obj = AddNew();

            object[] values = row.ItemArray;

            obj.currentValues = new rbSmartDictionary(ordinals, values);
            obj.originalValues = new rbSmartDictionary(ordinals, values, true);
            if (obj.m_modifiedColumns != null) obj.m_modifiedColumns = null;
            obj.rowState = rbDataRowState.Unchanged;

            IEntity iEntity = obj as IEntity;
            obj.rb.IsLazyLoadDisabled = true;

            return ordinals;
        }

        /// <summary>
        /// rbEntityCollection类调用数据访问器的时候调用.该方法封装了常用的逻辑. 
        /// </summary>
        /// <returns>rbDataRequest</returns>
        /// <seealso cref="rbDataRequest"/><seealso cref="rbDataProvider"/><seealso cref="IDataProvider"/>
        protected rbDataRequest CreateRequest()
        {
            rbDataRequest request = new rbDataRequest();
            request.Caller = this;

            rbConnection conn = this.rb.Connection;
            rbProviderSpecificMetadata providerMetadata = this.Meta.GetProviderMetadata(conn.ProviderMetadataKey);

            request.ConnectionString = conn.ConnectionString;
            request.CommandTimeout = conn.CommandTimeout;
            request.DataID = this.Meta.DataID;

            request.Catalog = conn.Catalog;
            request.Schema = conn.Schema;

            request.ProviderMetadata = this.Meta.GetProviderMetadata(conn.ProviderMetadataKey);
            request.SelectedColumns = selectedColumns;

            return request;
        }

        /// <summary>
        /// 在处理保存的时候，如果出错，可以通过遍历该属性排查.可以使用foreach遍历rbEntity，处理保存的时候检查他们的RowError属性，检查谁出错.
        /// </summary>
        /// <example>
        /// <code>
        /// EmployeesCollection coll = new EmployeesCollection();
        /// // 更改数据 ...
        /// try
        /// {
        ///    coll.Save();
        /// }
        /// catch
        /// {
        ///    foreach (Employees emp in coll.Errors)
        ///    { 
        ///        Console.WriteLine(emp.RowError);
        ///    }
        /// }
        /// </code>
        /// </example>
        public IEnumerable<T> Errors
        {
            get
            {
#if (!WindowsCE)
                if (deletedEntities == null)
                {
                    return from e in entities where e.rowError != null select e;
                }
                else
                {
                    return (from e in entities where e.rowError != null select e).Union
                           (from d in deletedEntities where d.rowError != null select d);
                }
#else
                List<T> errors = new List<T>();

                foreach (T entity in entities)
                {
                    if (entity.rowError != null)
                    {
                        errors.Add(entity);
                    }
                }

                if (deletedEntities != null)
                {
                    foreach (T entity in deletedEntities)
                    {
                        if (entity.rowError != null)
                        {
                            errors.Add(entity);
                        }
                    }
                }

                return errors;
#endif
            }
        }

        /// <summary>
        /// 向集合中添加实体.
        /// </summary>
        /// <param name="entity">添加到集合的实体.</param>
        /// <returns>刚添加的实体</returns>
        virtual public T AttachEntity(T entity)
        {
            entity.Collection = this;

            if (entity.rb.IsDeleted)
            {
                if (deletedEntities == null)
                {
                    deletedEntities = new List<T>();
                }

                deletedEntities.Add(entity);
                return entity;
            }

            // This entity now takes on the Collection's Connection info
            entity.rb.Connection.Name = this.rb.Connection.Name;

            entities.Add(entity);

            if (HasFilter && entitiesFilterBackup != null)
            {
                entitiesFilterBackup.Add(entity);
            }

            OnUpdateViewNotification(this, ListChangedType.ItemAdded, entity);

            return entity;
        }

        /// <summary>
        /// 从集合中移除的实体.
        /// </summary>
        /// <param name="entity">想要从集合中移除的实体.</param>
        /// <returns>刚移除的实体</returns>
        virtual public T DetachEntity(T entity)
        {
            entity.Collection = null;

            entities.Remove(entity);

            if (HasFilter && entitiesFilterBackup != null)
            {
                entitiesFilterBackup.Remove(entity);
            }

            //// This entity now takes on the Collection's Connection info
            //entity.rb.Connection.Name = this.rb.Connection.Name;

            OnUpdateViewNotification(this, ListChangedType.ItemDeleted, entity);

            return entity;
        }

        internal override void RemoveEntity(rbEntity entity)
        {
            DetachEntity((T)entity);
        }

        internal override void ClearDeletedEntries()
        {
            if (deletedEntities != null)
            {
                deletedEntities.Clear();
                deletedEntities = null;
            }
        }

        /// <summary>
        /// 接受所有变更.不应该在Save()之前调用，实际上你不会调用此方法.
        /// </summary>
        public override void AcceptChanges()
        {
            foreach (rbEntity entity in entities)
            {
                // Leave errors with rows in their current state
                if (entity.rowError == null)
                {
                    entity.AcceptChanges();
                }
            }

            if (deletedEntities != null)
            {
                for (int i = deletedEntities.Count - 1; i >= 0; i--)
                {
                    rbEntity entity = deletedEntities[i];
                    if (entity.rowError == null)
                    {
                        deletedEntities.Remove((T)entity);
                    }
                }

                if (deletedEntities.Count == 0)
                {
                    deletedEntities = null;
                }
            }
        }

        /// <summary>
        /// 回滚所有的更改到刚加载的时候，或者最后一次AcceptChanges调用的时候.
        /// </summary>
        public override void RejectChanges()
        {
            RaiseListChangeEvents_Disable();

            // Move the deleted rows back into the main entity list
            if (deletedEntities != null)
            {
                foreach (T obj in deletedEntities)
                {
                    entities.Add(obj);

                    // Add it to the filtered list too if need be
                    if (entitiesFilterBackup != null)
                    {
                        entitiesFilterBackup.Add(obj);
                    }
                }
            }
            deletedEntities = null;
           
            List<rbEntity> addedRows = new List<rbEntity>();
            foreach (T entity in entities)
            {
                if(entity.rowState == rbDataRowState.Added)
                {
                    // We're going to remove this in a moment
                    addedRows.Add(entity);
                }
                else
                {
                    if (entity.rowState == rbDataRowState.Modified || entity.rowState == rbDataRowState.Deleted)
                    {
                        entity.RejectChanges();
                    }
                }
            }

            foreach (T entity in addedRows)
            {
                entities.Remove(entity);
            }

            RaiseListChangeEvents_Restore();

            if (entities.RaiseListChangedEvents)
            {
                OnListChanged(this, new ListChangedEventArgs(ListChangedType.Reset, 0));
            }
        }

        /// <summary>
        /// 只支持Microsoft SQL Server.可以用于批量插入.该方法不会填充自增列或带默认值的列.
        /// </summary>
        virtual public void BulkInsert()
        {
            BulkInsert(null);           
        }

        /// <summary>
        /// 只支持Microsoft SQL Server.可以用于批量插入.该方法不会填充自增列或带默认值的列.
        /// </summary>
        /// <param name="bulkInsertOptions">其中一个例子是BulkInsert("KeepNulls", "FireTriggers") ，有疑问请参阅the ADO.NET provider的BulkCopyOptions</param>
        virtual public void BulkInsert(params string[] bulkInsertOptions)
        {
            if (entities.Count == 0) return;

            bool needToSendEvent = false;

            try
            {
                using (rbTransactionScope scope = new rbTransactionScope())
                {
                    rbDataRequest request;
                    rbDataProvider provider;
                    rbDataResponse response;

                    this.saveNestingCount++;

                    //=============================================================================
                    // SAVE INSERTS AND UPDATES
                    //=============================================================================
                    if (entities.Count > 0)
                    {
                        // Save added and modified rows. At this point we have removed the deleted rows
                        // and this.Table contains only, inserted, modified, and unchanged rows.
                        request = this.CreateRequest();
                        request.CollectionSavePacket = new List<rbEntitySavePacket>();

                        request.OnError += new rbDataRequest.OnErrorHandler(request_OnError);
                        request.ContinueUpdateOnError = true; // continueUpdateOnError;

                        // Execute PreSave logic
                        foreach (rbEntity entity in this.entities)
                        {
                            entity.rowError = null;

                            entity.PrepareSpecialFields();

                            if (entity.rb.RowState == rbDataRowState.Added)
                            {
                                rbEntitySavePacket packet;
                                packet.OriginalValues = entity.originalValues;
                                packet.CurrentValues = entity.currentValues;
                                packet.RowState = entity.rowState;
                                packet.ModifiedColumns = entity.rb.ModifiedColumns;
                                packet.Entity = entity;

                                request.CollectionSavePacket.Add(packet);
                            }
                        }

                        request.Columns = this.Meta.Columns;
                        request.BulkSave = true;
                        request.BulkSaveOptions = bulkInsertOptions;

                        if (request.CollectionSavePacket.Count > 0)
                        {
                            // Make the call to the DataProvider to physically commit the changes
                            provider = new rbDataProvider();
                            response = provider.rbSaveDataTable(request, this.rb.Connection.ProviderSignature);
                            needToSendEvent = true;

                            if (response.IsException)
                            {
                                throw response.Exception;
                            }
                        }
                    }

                    this.AcceptChanges();

                    scope.Complete();
                }
            }
            finally
            {
                this.saveNestingCount--;

                if (this.saveNestingCount == 0 && needToSendEvent == true)
                {
                    OnListChanged(this, new ListChangedEventArgs(ListChangedType.Reset, 0));
                }
            }  
        }

        #region Save

        /// <summary>
        /// 保存集合中所有修改的实体. 
        /// </summary>
        /// <remarks>
        /// rbSqlAccessType由存储在配置文件中的当前连接的'sqlAccessType'确定.
        /// 该值可以是DynamicSQL 或 StoredProcedure.
        /// </remarks>
        override public void Save()
        {
            IEntityCollection coll = this as IEntityCollection;
            this.Save(coll.Connection.SqlAccessType, false);
        }

        /// <summary>
        /// 保存集合中所有修改的实体.
        /// </summary>
        /// <param name="continueUpdateOnError">如果为true,其它记录出现错误的时候继续更新别的</param>
        override public void Save(bool continueUpdateOnError)
        {
            IEntityCollection coll = this as IEntityCollection;
            this.Save(coll.Connection.SqlAccessType, continueUpdateOnError);
        }

        /// <summary>
        /// 保存集合中所有修改的实体.
        /// </summary>
        /// <remarks>
        /// rbSqlAccessType由存储在配置文件中的当前连接的'sqlAccessType'确定.
        /// 该值可以是DynamicSQL 或 StoredProcedure.
        /// </remarks>
        /// <param name="sqlAccessType">DynamicSQL 或 StoredProcedure</param>
        virtual public void Save(rbSqlAccessType sqlAccessType)
        {
            Save(sqlAccessType, false);
        }


        /// <summary>
        /// 保存集合中所有修改的实体.
        /// </summary>
        /// <remarks>
        /// rbSqlAccessType由存储在配置文件中的当前连接的'sqlAccessType'确定.
        /// 该值可以是DynamicSQL 或 StoredProcedure.
        /// </remarks>
        /// <param name="sqlAccessType">DynamicSQL 或 StoredProcedure</param>
        /// <param name="continueUpdateOnError">如果为true,其它记录出现错误的时候继续更新别的</param>
        virtual public void Save(rbSqlAccessType sqlAccessType, bool continueUpdateOnError)
        {
            if (entities.Count == 0 && deletedEntities == null) return;

            bool needToSendEvent = false;

            try
            {
                using (rbTransactionScope scope = new rbTransactionScope())
                {
                    rbDataRequest request;
                    rbDataProvider provider;
                    rbDataResponse response;

                    this.saveNestingCount++;

                    //=============================================================================
                    // SAVE INSERTS AND UPDATES
                    //=============================================================================
                    if (entities.Count > 0)
                    {
                        // Save added and modified rows. At this point we have removed the deleted rows
                        // and this.Table contains only, inserted, modified, and unchanged rows.
                        request = this.CreateRequest();
                        request.CollectionSavePacket = new List<rbEntitySavePacket>();

                        request.OnError += new rbDataRequest.OnErrorHandler(request_OnError);
                        request.ContinueUpdateOnError = continueUpdateOnError;

                        // Execute PreSave logic
                        foreach (rbEntity entity in this.entities)
                        {
                            entity.rowError = null;

                            entity.PrepareSpecialFields();

                            entity.CommitPreSaves();
                            entity.ApplyPreSaveKeys();

                            if (entity.rb.RowState == rbDataRowState.Added || entity.rb.RowState == rbDataRowState.Modified)
                            {
                                rbEntitySavePacket packet;
                                packet.OriginalValues = entity.originalValues;
                                packet.CurrentValues = entity.currentValues;
                                packet.RowState = entity.rowState;
                                packet.ModifiedColumns = entity.rb.ModifiedColumns;
                                packet.Entity = entity;

                                request.CollectionSavePacket.Add(packet);
                            }
                        }

                        request.Columns = this.Meta.Columns;
                        request.SqlAccessType = sqlAccessType;


                        if (request.CollectionSavePacket.Count > 0)
                        {
                            // Make the call to the DataProvider to physically commit the changes
                            provider = new rbDataProvider();
                            response = provider.rbSaveDataTable(request, this.rb.Connection.ProviderSignature);
                            needToSendEvent = true;

                            if (!continueUpdateOnError && response.IsException)
                            {
                                throw response.Exception;
                            }
                        }

                        // PostSave action
                        foreach (rbEntity entity in this.entities)
                        {
                            entity.ApplyPostSaveKeys();
                            entity.ApplyPostOneSaveKeys();
                            entity.CommitPostSaves();
                            entity.CommitPostOneSaves();
                        }
                    }

                    //=============================================================================
                    // SAVE DELETES
                    //=============================================================================
                    if (deletedEntities != null && deletedEntities.Count > 0)
                    {
                        request = this.CreateRequest();
                        request.CollectionSavePacket = new List<rbEntitySavePacket>();

                        request.OnError += new rbDataRequest.OnErrorHandler(request_OnError);
                        request.ContinueUpdateOnError = continueUpdateOnError;

                        foreach (rbEntity entity in deletedEntities)
                        {
                            entity.rowError = null;
                            entity.ApplyPostSaveKeys();
                            entity.ApplyPostOneSaveKeys();
                            entity.CommitPostSaves();
                            entity.CommitPostOneSaves();

                            rbEntitySavePacket packet;
                            packet.OriginalValues = entity.originalValues;
                            packet.CurrentValues = entity.currentValues;
                            packet.RowState = entity.rowState;
                            packet.ModifiedColumns = entity.rb.ModifiedColumns;
                            packet.Entity = entity;

                            request.CollectionSavePacket.Add(packet);
                        }

                        request.Columns = this.Meta.Columns;
                        request.SqlAccessType = sqlAccessType;

                        // Make the call to the DataProvider to physically commit the changes
                        provider = new rbDataProvider();
                        response = provider.rbSaveDataTable(request, this.rb.Connection.ProviderSignature);
                        needToSendEvent = true;

                        if (!continueUpdateOnError && response.IsException)
                        {
                            throw response.Exception;
                        }
                    }

                    this.AcceptChanges();

                    scope.Complete();
                }
            }
            finally
            {
                this.saveNestingCount--;

                if (this.saveNestingCount == 0 && needToSendEvent == true)
                {
                    OnListChanged(this, new ListChangedEventArgs(ListChangedType.Reset, 0));
                }
            }
        }

        void request_OnError(rbEntitySavePacket packet, string error)
        {
            rbEntity entity = packet.Entity as rbEntity;

            if (entity != null)
            {
                entity.rowError = error;
            }
        }

        #endregion

        #region LoadAll

        /// <summary>
        /// 从数据库加载所有的实体.
        /// </summary>
        /// <remarks>
        /// rbSqlAccessType由存储在配置文件中的当前连接的'sqlAccessType'确定.
        /// 该值可以是DynamicSQL 或 StoredProcedure.
        /// </remarks>
        /// <returns>如果至少加载了一条，返回true.</returns>
        public override bool LoadAll()
        {
            if (this.rb.Connection.SqlAccessType == rbSqlAccessType.DynamicSQL)
                return this.GetDynamicQuery().Load();
            else
                return this.Load(rbQueryType.StoredProcedure, this.rb.spLoadAll);
        }

        /// <summary>
        /// 从数据库加载所有的实体.
        /// </summary>
        /// <remarks>
        /// rbSqlAccessType由存储在配置文件中的当前连接的'sqlAccessType'确定.
        /// 该值可以是DynamicSQL 或 StoredProcedure.
        /// </remarks>
        /// <example>
        /// <code>
        /// EmployeesCollection collection = new EmployeesCollection;
        /// Employees entity = new Employees;
        /// 
        /// collection.LoadAll(rbSqlAccessType.StoredProcedure);
        /// </code>
        /// </example>
        /// <param name="sqlAccessType">DynamicSQL 或 StoredProcedure.</param>
        /// <returns>T如果至少加载了一条，返回true.</returns>
        public override bool LoadAll(rbSqlAccessType sqlAccessType)
        {
            if (sqlAccessType == rbSqlAccessType.DynamicSQL)
                return this.GetDynamicQuery().Load();
            else
                return this.Load(rbQueryType.StoredProcedure, this.rb.spLoadAll);
        }

        #endregion

        #region Load

#if (LINQ)
        /// <summary>
        /// 允许使用 LinqToSql加载集合
        /// </summary>
        /// <param name="context">System.Data.Linq.DataContext</param>
        /// <param name="query">LINQ query</param>
        /// <returns>如果记录加载了返回true</returns>
        /// <remarks>
        /// 下面的例子展示了使用LINQ查询加载集合
        /// <code>
        /// EmployeesCollection coll = new EmployeesCollection();
        /// 
        /// DataContext context = new DataContext(coll.rb.Connection.ConnectionString);
        ///
        /// var linqQuery = context.GetTable&lt;Employees&gt;().Where(s => s.LastName == "Griffin")
        ///     .OrderBy(s => s.LastName); 
        /// 
        /// if(coll.Load(context, linqQuery))
        /// {
        ///     foreach (Employees emp in coll)
        ///     {
        ///         Console.WriteLine(emp.FirstName);
        ///     }
        /// }
        /// </code>
        /// </remarks>
        virtual public bool Load(DataContext context, IQueryable query)
        {
            bool loaded = false;
            try
            {
                rbDataRequest request = this.CreateRequest();

                request.LinqContext = context;
                request.LinqQuery = query;
                request.QueryType = rbQueryType.IQueryable;

                rbDataProvider provider = new rbDataProvider();
                rbDataResponse response = provider.rbLoadDataTable(request, this.rb.Connection.ProviderSignature);

                this.PopulateCollection(response.Table);
            }
            catch
            {
                throw;
            }
            finally
            {
                loaded = true;
            }

            return loaded;
        }

#endif

        /// <summary>
        /// 使用动态查询加载集合.也可以从自定义的实体中调用.
        /// </summary>
        /// <remarks>
        /// </remarks>
        /// <example>
        /// <code>
        /// public partial class EmployeesCollection : esEmployeesCollection
        /// {
        ///     public bool CustomLoad(string whereClause)
        ///     {
        ///			string sqlText = String.Empty;
        /// 
        ///         sqlText = "SELECT [LastName], [DepartmentID], [HireDate] ";
        ///         sqlText += "FROM [Employees] ";
        ///         sqlText += whereClause;
        /// 
        ///         return this.Load(rbQueryType.Text, sqlText);
        ///     }
        /// }
        /// </code>
        /// </example>
        /// <param name="queryType">请参阅<see cref="rbQueryType"/>.</param>
        /// <param name="query">SQL语句或存储过程名称.</param>
        /// <returns>加载成功返回true.</returns>
        virtual protected bool Load(rbQueryType queryType, string query)
        {
            return Load(queryType, query, null as rbParameters);
        }

        /// <summary>
        /// 使用动态查询加载集合.也可以从自定义的实体中调用.
        /// </summary>
        /// <remarks>
        /// </remarks>
        /// <example>
        /// <code>
        /// public partial class EmployeesCollection : esEmployeesCollection
        /// {
        ///     public bool CustomLoad()
        ///     {
        ///			string sqlText = String.Empty;
        /// 
        ///			sqlText = "SELECT [LastName], [DepartmentID], [HireDate] ";
        ///			sqlText += "FROM [Employees] ";
        ///			sqlText += "WHERE [DepartmentID] = {0} ";
        ///			sqlText += "AND [EmployeeID] = {1}";
        /// 
        ///			return this.Load(rbQueryType.Text, sqlText, 1, 23);
        ///     }
        /// }
        /// </code>
        /// </example>
        /// <param name="queryType">请参阅<see cref="rbQueryType"/>.</param>
        /// <param name="query">SQL语句或存储过程名称.</param>
        /// <param name="parameters">参数列表.</param>
        /// <returns>加载成功返回true.</returns>
        virtual protected bool Load(rbQueryType queryType, string query, params object[] parameters)
        {
            return Load(queryType, query, PackageParameters(parameters));
        }

        /// <summary>
        /// 使用动态查询加载集合.也可以从自定义的实体中调用.
        /// </summary>
        /// <remarks>
        /// </remarks>
        /// <example>
        /// <code>
        /// public partial class EmployeesCollection : esEmployeesCollection
        /// {
        ///     public bool CustomLoad(int empID)
        ///     {
        ///			string sqlText = String.Empty;
        ///			rbParameters esParams = new rbParameters();
        ///			esParams.Add("EmployeeID", empID);
        /// 
        ///			sqlText = "SELECT [LastName], [DepartmentID], [HireDate] ";
        ///			sqlText += "FROM [Employees] ";
        ///			sqlText += "WHERE [EmployeeID] = @EmployeeID";
        /// 
        ///			return this.Load(rbQueryType.Text, sqlText, esParams);
        ///     }
        /// }
        /// </code>
        /// </example>
        /// <param name="queryType">请参阅<see cref="rbQueryType"/>.</param>
        /// <param name="query">SQL语句或存储过程名称.</param>
        /// <param name="parms">参数列表.</param>
        /// <returns>加载成功返回true.</returns>
        virtual protected bool Load(rbQueryType queryType, string query, rbParameters parms)
        {
            bool loaded = false;
            try
            {
                rbDataRequest request = this.CreateRequest();

                request.Parameters = parms;
                request.QueryText = query;
                request.QueryType = queryType;

                rbDataProvider provider = new rbDataProvider();
                rbDataResponse response = provider.rbLoadDataTable(request, this.rb.Connection.ProviderSignature);

                this.PopulateCollection(response.Table);
            }
            catch
            {
                throw;
            }
            finally
            {
                loaded = (this.Count > 0);
            }

            return loaded;
        }

        #endregion

        #region Graph Operations

        #region IsGraphDirty()

        /// <summary>
        /// Returns true if any entity or collection in the object graph returns true from thier 
        /// respect IsDirty property.
        /// </summary>
        public override bool IsGraphDirty
        {
            get
            {
                return !rbVisitor.Visit(this, IsGraphDirtyCallback);
            }
        }

        private bool IsGraphDirtyCallback(rbVisitParameters p)
        {
            bool isClean = true;

            if (p.Node.NodeType == rbVisitableNodeType.Entity)
            {
                if (p.Node.Entity.GetCollection() == null)
                {
                    isClean = !p.Node.Entity.rb.IsDirty;
                }
            }
            else
            {
                isClean = !p.Node.Collection.IsDirty;
            }

            if (!isClean)
            {
                p.ProcessChildren = false;
            }

            return isClean;
        }

        #endregion

        #region AcceptChangesGraph()

        /// <summary>
        /// Will call AcceptChanges on the entire object graph.
        /// </summary>
        public void AcceptChangesGraph()
        {
            rbVisitor.Visit(this, AcceptChangesGraphCallback);
        }

        private bool AcceptChangesGraphCallback(rbVisitParameters p)
        {
            if (p.Node.NodeType == rbVisitableNodeType.Entity)
            {
                if (p.Node.Entity.GetCollection() == null)
                {
                    p.Node.Entity.AcceptChanges();
                }
            }
            else
            {
                p.Node.Collection.AcceptChanges();
            }

            return true;
        }

        #endregion

        #region RejectChangesGraph()

        /// <summary>
        /// 
        /// </summary>
        public void RejectChangesGraph()
        {
            rbVisitor.Visit(this, RejectChangesGraphCallback);
        }

        private bool RejectChangesGraphCallback(rbVisitParameters p)
        {
            if (p.Node.NodeType == rbVisitableNodeType.Entity)
            {
                if (p.Node.Entity.GetCollection() == null)
                {
                    p.Node.Entity.RejectChanges();
                }
            }
            else
            {
                p.Node.Collection.RejectChanges();
            }

            return true;
        }

        #endregion

        #region PruneGraph()

        /// <summary>
        /// 
        /// </summary>
        public void PruneGraph()
        {
            rbVisitor.Visit(this, PruneGraphEnterCallback, PruneGraphExitCallback);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="statesToPrune">The states you wish to prune, can be many such as PruneGraph(rbDataRowState.Modified | rbDataRowState.Deleted)</param>
        public void PruneGraph(rbDataRowState statesToPrune)
        {
            rbVisitor.Visit(this, PruneGraphWithStateEnterCallback, PruneGraphWithStatExitCallback, statesToPrune);
        }

        private bool PruneGraphEnterCallback(rbVisitParameters p)
        {
            if (p.Node.NodeType == rbVisitableNodeType.Collection)
            {
                p.Node.UserState = new List<rbEntity>();
            }

            if (p.Node.NodeType == rbVisitableNodeType.Entity)
            {
                if (p.Node.Entity.GetCollection() == null)
                {
                    if (!p.Node.Entity.rb.IsDirty && !p.Node.Entity.rb.IsGraphDirty)
                    {
                        p.Node.SetValueToNull(p.Parent.Obj);
                    }
                }
                else if (!p.Node.Entity.rb.IsDirty && !p.Node.Entity.rb.IsGraphDirty)
                {
                    List<rbEntity> list = p.Parent.UserState as List<rbEntity>;
                    list.Add(p.Node.Entity);
                }
            }
            else
            {
                p.Node.UserState = new List<rbEntity>();

                if (!p.Node.Collection.IsDirty && !p.Node.Collection.IsGraphDirty)
                {
                     p.Node.SetValueToNull(p.Parent.Obj);
                }
            }

            return true;
        }

        private bool PruneGraphExitCallback(rbVisitParameters p)
        {
            if (p.Node.NodeType == rbVisitableNodeType.Collection)
            {
                rbEntityCollectionBase coll = p.Node.Collection as rbEntityCollectionBase;

                List<rbEntity> list = p.Node.UserState as List<rbEntity>;

                foreach (rbEntity entity in list)
                {
                    coll.RemoveEntity(entity);
                }

                if( coll.Count == 0 && !coll.Count.Equals(p.Root))
                {
                    p.Node.SetValueToNull(p.Parent.Obj);
                }
            }

            return true;
        }

        private bool PruneGraphWithStateEnterCallback(rbVisitParameters p)
        {
            if (p.Node.NodeType == rbVisitableNodeType.Collection)
            {
                p.Node.UserState = new List<rbEntity>();
            }

            if (p.Node.NodeType == rbVisitableNodeType.Entity)
            {
                if (p.Node.Entity.GetCollection() == null)
                {
                    if (MatchesState(p.Node.Entity.rb.RowState, (rbDataRowState)p.UserState))
                    {
                        p.Node.SetValueToNull(p.Parent.Obj);
                    }
                }
                else if (MatchesState(p.Node.Entity.rb.RowState, (rbDataRowState)p.UserState))
                {
                    List<rbEntity> list = p.Parent.UserState as List<rbEntity>;
                    list.Add(p.Node.Entity);
                }
            }
            else
            {
                p.Node.UserState = new List<rbEntity>();

                if (MatchesState(rbDataRowState.Deleted, (rbDataRowState)p.UserState))
                {
                    p.Node.Collection.ClearDeletedEntries();
                }

                bool canSetToNull = true;
                foreach (rbEntity entity in p.Node.Collection)
                {
                    if (!MatchesState(entity.rb.RowState, (rbDataRowState)p.UserState))
                    {
                        canSetToNull = false;
                        break;
                    }
                }

                if (canSetToNull)
                {
                    p.Node.SetValueToNull(p.Parent.Obj);
                }
            }

            return true;
        }

        private bool PruneGraphWithStatExitCallback(rbVisitParameters p)
        {
            if (p.Node.NodeType == rbVisitableNodeType.Collection)
            {
                rbEntityCollectionBase coll = p.Node.Collection as rbEntityCollectionBase;

                List<rbEntity> list = p.Node.UserState as List<rbEntity>;

                foreach (rbEntity entity in list)
                {
                    coll.RemoveEntity(entity);
                }

                if (coll.Count == 0 && !coll.Count.Equals(p.Root))
                {
                    p.Node.SetValueToNull(p.Parent.Obj);
                }
            }

            return true;
        }

        static private bool MatchesState(rbDataRowState theState, rbDataRowState statesToPrune)
        {
            return (theState == (statesToPrune & theState)) ? true : false;
        }

        #endregion

        #endregion

        #region Protected Helper routines

        static private rbParameters PackageParameters(params object[] parameters)
        {
            rbParameters esParams = null;

            int i = 0;
            string sIndex = String.Empty;
            string param = String.Empty;

            if (parameters != null)
            {
                esParams = new rbParameters();

                foreach (object o in parameters)
                {
                    sIndex = i.ToString();
                    param = "p" + sIndex;
                    esParams.Add(param, o);
                    i++;
                }
            }

            return esParams;
        }


        #region ExecuteNonQuery
        /// <summary>
        /// 对连接执行Transact-SQL 语句并返回受影响的行.自定义的集合类中可以调用.
        /// 不能用该方法填充rbEntity.
        /// </summary>
        /// <remarks>
        /// 请参阅.NET文档的ExecuteNonQuery
        /// </remarks>
        /// <example>
        /// <code>
        /// public partial class EmployeesCollection : esEmployeesCollection
        /// {
        ///     public int CustomUpdate(string newName, int empID)
        ///     {
        ///			string sqlText = String.Empty;
        /// 
        ///         sqlText = "UPDATE [Employees] ";
        ///         sqlText += "SET [LastName] = '" + newName + "' ";
        ///         sqlText += "WHERE [EmployeeID] = " + empID;
        /// 
        ///         return this.ExecuteNonQuery(rbQueryType.Text, sqlText);
        ///     }
        /// }
        /// </code>
        /// </example>
        /// <param name="queryType">请参阅<see cref="rbQueryType"/>.</param>
        /// <param name="query">SQL语句或存储过程名称.</param>
        /// <returns>影响的行数.</returns>
        protected internal int ExecuteNonQuery(rbQueryType queryType, string query)
        {
            return ExecuteNonQuery(queryType, query, null as rbParameters);
        }

        /// <summary>
        /// 对连接执行Transact-SQL 语句并返回受影响的行.自定义的集合类中可以调用.
        /// 不能用该方法填充rbEntity.
        /// </summary>
        /// <remarks>
        /// 请参阅.NET文档的ExecuteNonQuery
        /// </remarks>
        /// <example>
        /// <code>
        /// public partial class EmployeesCollection : esEmployeesCollection
        /// {
        ///     public int CustomUpdate(string newName, int empID)
        ///     {
        ///			string sqlText = String.Empty;
        /// 
        ///         sqlText = "UPDATE [Employees] ";
        ///         sqlText += "SET [LastName] = {0} ";
        ///         sqlText += "WHERE [EmployeeID] = {1}";
        /// 
        ///         return this.ExecuteNonQuery(rbQueryType.Text, sqlText, newName, empID);
        ///     }
        /// }
        /// </code>
        /// </example>
        /// <param name="queryType">请参阅<see cref="rbQueryType"/>.</param>
        /// <param name="query">SQL语句或存储过程名称.</param>
        /// <param name="parameters">参数列表.</param>
        /// <returns>影响的行数.</returns>
        protected internal int ExecuteNonQuery(rbQueryType queryType, string query, params object[] parameters)
        {
            return ExecuteNonQuery(queryType, query, PackageParameters(parameters));
        }

        /// <summary>
        /// 对连接执行Transact-SQL 语句并返回受影响的行.自定义的集合类中可以调用.
        /// 不能用该方法填充rbEntity.
        /// </summary>
        /// <remarks>
        /// 请参阅.NET文档的ExecuteNonQuery
        /// </remarks>
        /// <example>
        /// <code>
        /// public partial class EmployeesCollection : esEmployeesCollection
        /// {
        ///     public int CustomUpdate(string newName)
        ///     {
        ///			string sqlText = String.Empty;
        ///			rbParameters esParams = new rbParameters();
        ///			esParams.Add("FirstName", newName);
        ///			esParams.Add("LastName", "Doe");
        ///			esParams.Add("Salary", 27.53);
        /// 
        ///         sqlText = "UPDATE [Employees] ";
        ///			sqlText += "SET [FirstName] =  @FirstName ";
        ///			sqlText += "WHERE [LastName] = @LastName ";
        ///			sqlText += "AND [Salary] = @Salary";
        /// 
        ///         return this.ExecuteNonQuery(rbQueryType.Text, sqlText, esParams);
        ///     }
        /// }
        /// </code>
        /// </example>
        /// <param name="queryType">请参阅<see cref="rbQueryType"/>.</param>
        /// <param name="query">SQL语句或存储过程名称.</param>
        /// <param name="parms">参数列表. See <see cref="rbParameters"/>.</param>
        /// <returns>影响的行数.</returns>
        protected internal int ExecuteNonQuery(rbQueryType queryType, string query, rbParameters parms)
        {
            rbDataRequest request = this.CreateRequest();

            request.Parameters = parms;
            request.QueryText = query;
            request.QueryType = queryType;

            rbDataProvider provider = new rbDataProvider();
            rbDataResponse response = provider.ExecuteNonQuery(request, this.rb.Connection.ProviderSignature);

            return response.RowsEffected;
        }

        /// <summary>
        /// 对连接执行Transact-SQL 语句并返回受影响的行.自定义的集合类中可以调用.
        /// 不能用该方法填充rbEntity.
        /// </summary>
        /// <remarks>
        /// 请参阅.NET文档的ExecuteNonQuery
        /// </remarks>
        /// <example>
        /// <code>
        /// public partial class EmployeesCollection : esEmployeesCollection
        /// {
        ///     public int CustomUpdate()
        ///     {
        ///			return this.ExecuteNonQuery(this.rb.Schema, "MyStoredProc");
        ///     }
        /// }
        /// </code>
        /// </example>
        /// <param name="schema">See <see cref="IEntity.Schema"/>.</param>
        /// <param name="storedProcedure">存储过程名称.</param>
        /// <returns>影响的行数.</returns>
        protected internal int ExecuteNonQuery(string schema, string storedProcedure)
        {
            return ExecuteNonQuery(schema, storedProcedure, null as rbParameters);
        }

        /// <summary>
        /// 对连接执行Transact-SQL 语句并返回受影响的行.自定义的集合类中可以调用.
        /// 不能用该方法填充rbEntity.
        /// </summary>
        /// <remarks>
        /// 请参阅.NET文档的ExecuteNonQuery
        /// </remarks>
        /// <example>
        /// <code>
        /// public partial class EmployeesCollection : esEmployeesCollection
        /// {
        ///     public int CustomUpdate(string newName, int empID)
        ///     {
        ///			return this.ExecuteNonQuery(this.rb.Schema, "MyStoredProc", newName, empID);
        ///     }
        /// }
        /// </code>
        /// </example>
        /// <param name="schema">See <see cref="IEntity.Schema"/>.</param>
        /// <param name="storedProcedure">存储过程名称.</param>
        /// <param name="parameters">参数列表.</param>
        /// <returns>影响的行数.</returns>
        protected internal int ExecuteNonQuery(string schema, string storedProcedure, params object[] parameters)
        {
            return ExecuteNonQuery(schema, storedProcedure, PackageParameters(parameters));
        }

        /// <summary>
        /// 对连接执行Transact-SQL 语句并返回受影响的行.自定义的集合类中可以调用.
        /// 不能用该方法填充rbEntity.
        /// </summary>
        /// <remarks>
        /// 请参阅.NET文档的ExecuteNonQuery
        /// </remarks>
        /// <example>
        /// <code>
        /// public partial class EmployeesCollection : esEmployeesCollection
        /// {
        ///     public int CustomUpdate(string newName)
        ///     {
        ///			rbParameters esParams = new rbParameters();
        ///			esParams.Add("FirstName", newName);
        ///			esParams.Add("LastName", "Doe");
        ///			esParams.Add("Salary", 27.53);
        /// 
        ///			return this.ExecuteNonQuery(this.rb.Schema, "MyStoredProc", esParams);
        ///     }
        /// }
        /// </code>
        /// </example>
        /// <param name="schema">See <see cref="IEntity.Schema"/>.</param>
        /// <param name="storedProcedure">存储过程名称.</param>
        /// <param name="parameters">参数列表. See <see cref="rbParameters"/>.</param>
        /// <returns>影响的行数.</returns>
        protected internal int ExecuteNonQuery(string schema, string storedProcedure, rbParameters parameters)
        {
            rbDataRequest request = this.CreateRequest();

            request.Parameters = parameters;
            request.Schema = schema;
            request.QueryText = storedProcedure;
            request.QueryType = rbQueryType.StoredProcedure;

            rbDataProvider provider = new rbDataProvider();
            rbDataResponse response = provider.ExecuteNonQuery(request, this.rb.Connection.ProviderSignature);

            return response.RowsEffected;
        }

        /// <summary>
        /// 对连接执行Transact-SQL 语句并返回受影响的行.自定义的集合类中可以调用.
        /// 不能用该方法填充rbEntity.
        /// </summary>
        /// <remarks>
        /// 请参阅.NET文档的ExecuteNonQuery
        /// </remarks>
        /// <example>
        /// <code>
        /// public partial class EmployeesCollection : esEmployeesCollection
        /// {
        ///     public int CustomUpdate()
        ///     {
        ///			return this.ExecuteNonQuery(this.rb.Catalog, this.rb.Schema, "MyStoredProc");
        ///     }
        /// }
        /// </code>
        /// </example>
        /// <param name="catalog">"Northwind"就是例子. 请参阅<see cref="IEntity.Catalog"/>.</param>
        /// <param name="schema">"dbo" 就是例子. 请参阅<see cref="IEntity.Schema"/>.</param>
        /// <param name="storedProcedure">存储过程名称.</param>
        /// <returns>影响的行数.</returns>
        protected internal int ExecuteNonQuery(string catalog, string schema, string storedProcedure)
        {
            return ExecuteNonQuery(catalog, schema, storedProcedure, null as rbParameters);
        }

        /// <summary>
        /// 对连接执行Transact-SQL 语句并返回受影响的行.自定义的集合类中可以调用.
        /// 不能用该方法填充rbEntity.
        /// </summary>
        /// <remarks>
        /// 请参阅.NET文档的ExecuteNonQuery
        /// </remarks>
        /// <example>
        /// <code>
        /// public partial class EmployeesCollection : esEmployeesCollection
        /// {
        ///     public int CustomUpdate(string newName, int empID)
        ///     {
        ///			return this.ExecuteNonQuery(this.rb.Catalog, this.rb.Schema, "MyStoredProc", newName, empID);
        ///     }
        /// }
        /// </code>
        /// </example>
        /// <param name="catalog">"Northwind"就是例子. 请参阅<see cref="IEntity.Catalog"/>.</param>
        /// <param name="schema">"dbo" 就是例子. 请参阅<see cref="IEntity.Schema"/>.</param>
        /// <param name="storedProcedure">存储过程名称.</param>
        /// <param name="parameters">参数列表.</param>
        /// <returns>影响的行数.</returns>
        protected internal int ExecuteNonQuery(string catalog, string schema, string storedProcedure, params object[] parameters)
        {
            return ExecuteNonQuery(catalog, schema, storedProcedure, PackageParameters(parameters));
        }

        /// <summary>
        /// 对连接执行Transact-SQL 语句并返回受影响的行.自定义的集合类中可以调用.
        /// 不能用该方法填充rbEntity.
        /// </summary>
        /// <remarks>
        /// 请参阅.NET文档的ExecuteNonQuery
        /// </remarks>
        /// <example>
        /// <code>
        /// public partial class EmployeesCollection : esEmployeesCollection
        /// {
        ///     public int CustomUpdate(string newName)
        ///     {
        ///			rbParameters esParams = new rbParameters();
        ///			esParams.Add("FirstName", newName);
        ///			esParams.Add("LastName", "Doe");
        ///			esParams.Add("Salary", 27.53);
        /// 
        ///			return this.ExecuteNonQuery(this.rb.Catalog, this.rb.Schema, "MyStoredProc", esParams);
        ///     }
        /// }
        /// </code>
        /// </example>
        /// <param name="catalog">"Northwind"就是例子. 请参阅<see cref="IEntity.Catalog"/>.</param>
        /// <param name="schema">"dbo" 就是例子. 请参阅<see cref="IEntity.Schema"/>.</param>
        /// <param name="storedProcedure">存储过程名称.</param>
        /// <param name="parameters">参数列表.</param>
        /// <returns>影响的行数.</returns>
        protected internal int ExecuteNonQuery(string catalog, string schema, string storedProcedure, rbParameters parameters)
        {
            rbDataRequest request = this.CreateRequest();

            request.Parameters = parameters;
            request.Catalog = catalog;
            request.Schema = schema;
            request.QueryText = storedProcedure;
            request.QueryType = rbQueryType.StoredProcedure;

            rbDataProvider provider = new rbDataProvider();
            rbDataResponse response = provider.ExecuteNonQuery(request, this.rb.Connection.ProviderSignature);

            return response.RowsEffected;
        }

        #endregion

        #region ExecuteReader

        /// <summary>
        /// 自定义的rbEntityCollection可以调用.不可以填充实体.
        /// </summary>
        /// <remarks>
        /// 请参阅.NET文档的ExecuteReader.
        /// </remarks>
        /// <example>
        /// 请参阅 <see cref="ExecuteNonQuery"/> 例子,重载和参数.
        /// </example>
        /// <returns>ExecuteReader.</returns>
        protected internal IDataReader ExecuteReader(rbQueryType queryType, string query)
        {
            return ExecuteReader(queryType, query, null as rbParameters);
        }

        /// <summary>
        /// 自定义的rbEntityCollection可以调用.不可以填充实体.
        /// </summary>
        /// <remarks>
        /// 请参阅.NET文档的ExecuteReader.
        /// </remarks>
        /// <example>
        /// 请参阅 <see cref="ExecuteNonQuery"/> 例子,重载和参数.
        /// </example>
        /// <returns>ExecuteReader.</returns>
        protected internal IDataReader ExecuteReader(rbQueryType queryType, string query, params object[] parameters)
        {
            return ExecuteReader(queryType, query, PackageParameters(parameters));
        }

        /// <summary>
        /// 自定义的rbEntityCollection可以调用.不可以填充实体.
        /// </summary>
        /// <remarks>
        /// 请参阅.NET文档的ExecuteReader.
        /// </remarks>
        /// <example>
        /// 请参阅 <see cref="ExecuteNonQuery"/> 例子,重载和参数.
        /// </example>
        /// <returns>ExecuteReader.</returns>
        protected internal IDataReader ExecuteReader(rbQueryType queryType, string query, rbParameters parms)
        {
            rbDataRequest request = this.CreateRequest();

            request.Parameters = parms;
            request.QueryText = query;
            request.QueryType = queryType;

            rbDataProvider provider = new rbDataProvider();
            rbDataResponse response = provider.ExecuteReader(request, this.rb.Connection.ProviderSignature);

            return response.DataReader;
        }

        /// <summary>
        /// 自定义的rbEntityCollection可以调用.不可以填充实体.
        /// </summary>
        /// <remarks>
        /// 请参阅.NET文档的ExecuteReader.
        /// </remarks>
        /// <example>
        /// 请参阅 <see cref="ExecuteNonQuery"/> 例子,重载和参数.
        /// </example>
        /// <returns>ExecuteReader.</returns>
        protected internal IDataReader ExecuteReader(string schema, string storedProcedure)
        {
            return ExecuteReader(schema, storedProcedure, null as rbParameters);
        }

        /// <summary>
        /// 自定义的rbEntityCollection可以调用.不可以填充实体.
        /// </summary>
        /// <remarks>
        /// 请参阅.NET文档的ExecuteReader.
        /// </remarks>
        /// <example>
        /// 请参阅 <see cref="ExecuteNonQuery"/> 例子,重载和参数.
        /// </example>
        /// <returns>ExecuteReader.</returns>
        protected internal IDataReader ExecuteReader(string schema, string storedProcedure, params object[] parameters)
        {
            return ExecuteReader(schema, storedProcedure, PackageParameters(parameters));
        }

        /// <summary>
        /// 自定义的rbEntityCollection可以调用.不可以填充实体.
        /// </summary>
        /// <remarks>
        /// 请参阅.NET文档的ExecuteReader.
        /// </remarks>
        /// <example>
        /// 请参阅 <see cref="ExecuteNonQuery"/> 例子,重载和参数.
        /// </example>
        /// <returns>ExecuteReader.</returns>
        protected internal IDataReader ExecuteReader(string schema, string storedProcedure, rbParameters parameters)
        {
            rbDataRequest request = this.CreateRequest();

            request.Parameters = parameters;
            request.Schema = schema;
            request.QueryText = storedProcedure;
            request.QueryType = rbQueryType.StoredProcedure;

            rbDataProvider provider = new rbDataProvider();
            rbDataResponse response = provider.ExecuteReader(request, this.rb.Connection.ProviderSignature);

            return response.DataReader;
        }

        /// <summary>
        /// 自定义的rbEntityCollection可以调用.不可以填充实体.
        /// </summary>
        /// <remarks>
        /// 请参阅.NET文档的ExecuteReader.
        /// </remarks>
        /// <example>
        /// 请参阅 <see cref="ExecuteNonQuery"/> 例子,重载和参数.
        /// </example>
        /// <returns>ExecuteReader.</returns>
        protected internal IDataReader ExecuteReader(string catalog, string schema, string storedProcedure)
        {
            return ExecuteReader(catalog, schema, storedProcedure, null as rbParameters);
        }

        /// <summary>
        /// 自定义的rbEntityCollection可以调用.不可以填充实体.
        /// </summary>
        /// <remarks>
        /// 请参阅.NET文档的ExecuteReader.
        /// </remarks>
        /// <example>
        /// 请参阅 <see cref="ExecuteNonQuery"/> 例子,重载和参数.
        /// </example>
        /// <returns>ExecuteReader.</returns>
        protected internal IDataReader ExecuteReader(string catalog, string schema, string storedProcedure, params object[] parameters)
        {
            return ExecuteReader(catalog, schema, storedProcedure, PackageParameters(parameters));
        }

        /// <summary>
        /// 自定义的rbEntityCollection可以调用.不可以填充实体.
        /// </summary>
        /// <remarks>
        /// 请参阅.NET文档的ExecuteReader.
        /// </remarks>
        /// <example>
        /// 请参阅 <see cref="ExecuteNonQuery"/> 例子,重载和参数.
        /// </example>
        /// <returns>ExecuteReader.</returns>
        protected internal IDataReader ExecuteReader(string catalog, string schema, string storedProcedure, rbParameters parameters)
        {
            rbDataRequest request = this.CreateRequest();

            request.Parameters = parameters;
            request.Catalog = catalog;
            request.Schema = schema;
            request.QueryText = storedProcedure;
            request.QueryType = rbQueryType.StoredProcedure;

            rbDataProvider provider = new rbDataProvider();
            rbDataResponse response = provider.ExecuteReader(request, this.rb.Connection.ProviderSignature);

            return response.DataReader;
        }

        #endregion

        #region ExecuteScalar

        /// <summary>
        /// 执行查询，并返回查询所返回的结果集中第一行的第一列.忽略其他列或行.
        /// 不能用该方法填充rbEntity.
        /// </summary>
        /// <remarks>
        /// 请参阅.NET文档的ExecuteScalar.
        /// </remarks>
        /// <example>
        /// 请参阅 <see cref="ExecuteNonQuery"/> 例子,重载和参数.
        /// </example>
        /// <returns>第一行第一列的值.</returns>
        protected internal object ExecuteScalar(rbQueryType queryType, string query)
        {
            return ExecuteScalar(queryType, query, null as rbParameters);
        }

        /// <summary>
        /// 执行查询，并返回查询所返回的结果集中第一行的第一列.忽略其他列或行.
        /// 不能用该方法填充rbEntity.
        /// </summary>
        /// <remarks>
        /// 请参阅.NET文档的ExecuteScalar.
        /// </remarks>
        /// <example>
        /// 请参阅 <see cref="ExecuteNonQuery"/> 例子,重载和参数.
        /// </example>
        /// <returns>第一行第一列的值.</returns>
        protected internal object ExecuteScalar(rbQueryType queryType, string query, params object[] parameters)
        {
            return ExecuteScalar(queryType, query, PackageParameters(parameters));
        }

        /// <summary>
        /// 执行查询，并返回查询所返回的结果集中第一行的第一列.忽略其他列或行.
        /// 不能用该方法填充rbEntity.
        /// </summary>
        /// <remarks>
        /// 请参阅.NET文档的ExecuteScalar.
        /// </remarks>
        /// <example>
        /// 请参阅 <see cref="ExecuteNonQuery"/> 例子,重载和参数.
        /// </example>
        /// <returns>第一行第一列的值.</returns>
        protected internal object ExecuteScalar(rbQueryType queryType, string query, rbParameters parms)
        {
            rbDataRequest request = this.CreateRequest();

            request.Parameters = parms;
            request.QueryText = query;
            request.QueryType = queryType;

            rbDataProvider provider = new rbDataProvider();
            rbDataResponse response = provider.ExecuteScalar(request, this.rb.Connection.ProviderSignature);

            return response.Scalar;
        }

        /// <summary>
        /// 执行查询，并返回查询所返回的结果集中第一行的第一列.忽略其他列或行.
        /// 不能用该方法填充rbEntity.
        /// </summary>
        /// <remarks>
        /// 请参阅.NET文档的ExecuteScalar.
        /// </remarks>
        /// <example>
        /// 请参阅 <see cref="ExecuteNonQuery"/> 例子,重载和参数.
        /// </example>
        /// <returns>第一行第一列的值.</returns>
        protected internal object ExecuteScalar(string schema, string storedProcedure)
        {
            return ExecuteScalar(schema, storedProcedure, null as rbParameters);
        }

        /// <summary>
        /// 执行查询，并返回查询所返回的结果集中第一行的第一列.忽略其他列或行.
        /// 不能用该方法填充rbEntity.
        /// </summary>
        /// <remarks>
        /// 请参阅.NET文档的ExecuteScalar.
        /// </remarks>
        /// <example>
        /// 请参阅 <see cref="ExecuteNonQuery"/> 例子,重载和参数.
        /// </example>
        /// <returns>第一行第一列的值.</returns>
        protected internal object ExecuteScalar(string schema, string storedProcedure, params object[] parameters)
        {
            return ExecuteScalar(schema, storedProcedure, PackageParameters(parameters));
        }

        /// <summary>
        /// 执行查询，并返回查询所返回的结果集中第一行的第一列.忽略其他列或行.
        /// 不能用该方法填充rbEntity.
        /// </summary>
        /// <remarks>
        /// 请参阅.NET文档的ExecuteScalar.
        /// </remarks>
        /// <example>
        /// 请参阅 <see cref="ExecuteNonQuery"/> 例子,重载和参数.
        /// </example>
        /// <returns>第一行第一列的值.</returns>
        protected internal object ExecuteScalar(string schema, string storedProcedure, rbParameters parameters)
        {
            rbDataRequest request = this.CreateRequest();

            request.Parameters = parameters;
            request.Schema = schema;
            request.QueryText = storedProcedure;
            request.QueryType = rbQueryType.StoredProcedure;

            rbDataProvider provider = new rbDataProvider();
            rbDataResponse response = provider.ExecuteScalar(request, this.rb.Connection.ProviderSignature);

            return response.Scalar;
        }

        /// <summary>
        /// 执行查询，并返回查询所返回的结果集中第一行的第一列.忽略其他列或行.
        /// 不能用该方法填充rbEntity.
        /// </summary>
        /// <remarks>
        /// 请参阅.NET文档的ExecuteScalar.
        /// </remarks>
        /// <example>
        /// 请参阅 <see cref="ExecuteNonQuery"/> 例子,重载和参数.
        /// </example>
        /// <returns>第一行第一列的值.</returns>
        protected internal object ExecuteScalar(string catalog, string schema, string storedProcedure)
        {
            return ExecuteScalar(catalog, schema, storedProcedure, null as rbParameters);
        }

        /// <summary>
        /// 执行查询，并返回查询所返回的结果集中第一行的第一列.忽略其他列或行.
        /// 不能用该方法填充rbEntity.
        /// </summary>
        /// <remarks>
        /// 请参阅.NET文档的ExecuteScalar.
        /// </remarks>
        /// <example>
        /// 请参阅 <see cref="ExecuteNonQuery"/> 例子,重载和参数.
        /// </example>
        /// <returns>第一行第一列的值.</returns>
        protected internal object ExecuteScalar(string catalog, string schema, string storedProcedure, params object[] parameters)
        {
            return ExecuteScalar(catalog, schema, storedProcedure, PackageParameters(parameters));
        }

        /// <summary>
        /// 执行查询，并返回查询所返回的结果集中第一行的第一列.忽略其他列或行.
        /// 不能用该方法填充rbEntity.
        /// </summary>
        /// <remarks>
        /// 请参阅.NET文档的ExecuteScalar.
        /// </remarks>
        /// <example>
        /// 请参阅 <see cref="ExecuteNonQuery"/> 例子,重载和参数.
        /// </example>
        /// <returns>第一行第一列的值.</returns>
        protected internal object ExecuteScalar(string catalog, string schema, string storedProcedure, rbParameters parameters)
        {
            rbDataRequest request = this.CreateRequest();

            request.Parameters = parameters;
            request.Catalog = catalog;
            request.Schema = schema;
            request.QueryText = storedProcedure;
            request.QueryType = rbQueryType.StoredProcedure;

            rbDataProvider provider = new rbDataProvider();
            rbDataResponse response = provider.ExecuteScalar(request, this.rb.Connection.ProviderSignature);

            return response.Scalar;
        }

        #endregion

        #region ExecuteScalar<T>

        /// <summary>
        /// 执行查询，并返回查询所返回的结果集中第一行的第一列.忽略其他列或行.并且将返回值转换为D类型
        /// 不能用该方法填充rbEntity.
        /// </summary>
        /// <remarks>
        /// 请参阅.NET文档的ExecuteScalar.
        /// </remarks>
        /// <example>
        /// 请参阅 <see cref="ExecuteNonQuery"/> 例子,重载和参数.
        /// </example>
        /// <returns>D.</returns>
        internal D ExecuteScalar<D>(rbQueryType queryType, string query)
        {
            return (D)ExecuteScalar<D>(queryType, query, null as rbParameters);
        }

        /// <summary>
        /// 执行查询，并返回查询所返回的结果集中第一行的第一列.忽略其他列或行.并且将返回值转换为D类型
        /// 不能用该方法填充rbEntity.
        /// </summary>
        /// <remarks>
        /// 请参阅.NET文档的ExecuteScalar.
        /// </remarks>
        /// <example>
        /// 请参阅 <see cref="ExecuteNonQuery"/> 例子,重载和参数.
        /// </example>
        /// <returns>D.</returns>
        internal D ExecuteScalar<D>(rbQueryType queryType, string query, params object[] parameters)
        {
            return (D)ExecuteScalar<D>(queryType, query, PackageParameters(parameters));
        }

        /// <summary>
        /// 执行查询，并返回查询所返回的结果集中第一行的第一列.忽略其他列或行.并且将返回值转换为D类型
        /// 不能用该方法填充rbEntity.
        /// </summary>
        /// <remarks>
        /// 请参阅.NET文档的ExecuteScalar.
        /// </remarks>
        /// <example>
        /// 请参阅 <see cref="ExecuteNonQuery"/> 例子,重载和参数.
        /// </example>
        /// <returns>D.</returns>
        internal D ExecuteScalar<D>(rbQueryType queryType, string query, rbParameters parms)
        {
            rbDataRequest request = this.CreateRequest();

            request.Parameters = parms;
            request.QueryText = query;
            request.QueryType = queryType;

            rbDataProvider provider = new rbDataProvider();
            rbDataResponse response = provider.ExecuteScalar(request, this.rb.Connection.ProviderSignature);

            if (response.Scalar == DBNull.Value)
            {
                response.Scalar = null;
            }

            return (D)response.Scalar;
        }

        /// <summary>
        /// 执行查询，并返回查询所返回的结果集中第一行的第一列.忽略其他列或行.并且将返回值转换为D类型
        /// 不能用该方法填充rbEntity.
        /// </summary>
        /// <remarks>
        /// 请参阅.NET文档的ExecuteScalar.
        /// </remarks>
        /// <example>
        /// 请参阅 <see cref="ExecuteNonQuery"/> 例子,重载和参数.
        /// </example>
        /// <returns>D.</returns>
        internal D ExecuteScalar<D>(string schema, string storedProcedure)
        {
            return (D)ExecuteScalar<D>(schema, storedProcedure, null as rbParameters);
        }

        /// <summary>
        /// 执行查询，并返回查询所返回的结果集中第一行的第一列.忽略其他列或行.并且将返回值转换为D类型
        /// 不能用该方法填充rbEntity.
        /// </summary>
        /// <remarks>
        /// 请参阅.NET文档的ExecuteScalar.
        /// </remarks>
        /// <example>
        /// 请参阅 <see cref="ExecuteNonQuery"/> 例子,重载和参数.
        /// </example>
        /// <returns>D.</returns>
        internal D ExecuteScalar<D>(string schema, string storedProcedure, params object[] parameters)
        {
            return (D)ExecuteScalar<D>(schema, storedProcedure, PackageParameters(parameters));
        }

        /// <summary>
        /// 执行查询，并返回查询所返回的结果集中第一行的第一列.忽略其他列或行.并且将返回值转换为D类型
        /// 不能用该方法填充rbEntity.
        /// </summary>
        /// <remarks>
        /// 请参阅.NET文档的ExecuteScalar.
        /// </remarks>
        /// <example>
        /// 请参阅 <see cref="ExecuteNonQuery"/> 例子,重载和参数.
        /// </example>
        /// <returns>D.</returns>
        internal D ExecuteScalar<D>(string schema, string storedProcedure, rbParameters parameters)
        {
            rbDataRequest request = this.CreateRequest();

            request.Parameters = parameters;
            request.Schema = schema;
            request.QueryText = storedProcedure;
            request.QueryType = rbQueryType.StoredProcedure;

            rbDataProvider provider = new rbDataProvider();
            rbDataResponse response = provider.ExecuteScalar(request, this.rb.Connection.ProviderSignature);

            if (response.Scalar == DBNull.Value)
            {
                response.Scalar = null;
            }

            return (D)response.Scalar;
        }

        #endregion

        #region FillDataTable

        /// <summary>
        /// 自定义的实体集合可以调用.不能用该方法填充实体.
        /// </summary>
        /// <example>
        /// <code>
        /// public partial class EmployeesCollection : esEmployeesCollection
        /// {
        ///     public DataTable CustomFillTable()
        ///     {
        ///			string sqlText = String.Empty;
        /// 
        ///         sqlText = "SELECT * ";
        ///         sqlText += "FROM [Employees] ";
        ///         sqlText += "WHERE [LastName] = {0} ";
        ///         sqlText += "OR [LastName] = {1}";
        /// 
        ///         return this.FillDataTable(rbQueryType.Text, sqlText, "Doe", "Johnson");
        ///     }
        /// }
        /// </code>
        /// </example>
        /// <param name="queryType">请参阅<see cref="rbQueryType"/>.</param>
        /// <param name="query">SQL语句或存储过程名称.</param>
        /// <returns>包含结果集的DataTable.</returns>
        protected internal DataTable FillDataTable(rbQueryType queryType, string query)
        {
            return FillDataTable(queryType, query, null as rbParameters);
        }

        /// <summary>
        /// 自定义的实体集合可以调用.不能用该方法填充实体.
        /// </summary>
        /// <param name="queryType">请参阅<see cref="rbQueryType"/>.</param>
        /// <param name="query">SQL语句或存储过程名称.</param>
        /// <param name="parameters">参数列表.</param>
        /// <returns>包含结果集的DataTable.</returns>
        protected internal DataTable FillDataTable(rbQueryType queryType, string query, params object[] parameters)
        {
            return FillDataTable(queryType, query, PackageParameters(parameters));
        }

        /// <summary>
        /// 自定义的实体集合可以调用.不能用该方法填充实体.
        /// </summary>
        /// <param name="queryType">请参阅<see cref="rbQueryType"/>.</param>
        /// <param name="query">SQL语句或存储过程名称.</param>
        /// <param name="parms">参数列表.</param>
        /// <returns>包含结果集的DataTable.</returns>
        protected internal DataTable FillDataTable(rbQueryType queryType, string query, rbParameters parms)
        {
            rbDataRequest request = this.CreateRequest();

            request.Parameters = parms;
            request.QueryText = query;
            request.QueryType = queryType;

            rbDataProvider provider = new rbDataProvider();
            rbDataResponse response = provider.FillDataTable(request, this.rb.Connection.ProviderSignature);
            return response.Table;
        }

        /// <summary>
        /// 自定义的实体集合可以调用.不能用该方法填充实体.
        /// </summary>
        /// <example>
        /// <code>
        /// public partial class EmployeesCollection : esEmployeesCollection
        /// {
        ///     public DataTable CustomFillTable()
        ///     {
        ///			return this.FillDataTable(this.rb.Schema, "MyStoredProc");
        ///     }
        /// }
        /// </code>
        /// </example>
        /// <param name="schema">See <see cref="IEntity.Schema"/>.</param>
        /// <param name="storedProcedure">存储过程名称.</param>
        /// <returns>包含结果集的DataTable.</returns>
        protected internal DataTable FillDataTable(string schema, string storedProcedure)
        {
            return FillDataTable(schema, storedProcedure, null as rbParameters);
        }

        /// <summary>
        /// 自定义的实体集合可以调用.不能用该方法填充实体.
        /// </summary>
        /// <param name="schema">See <see cref="IEntity.Schema"/>.</param>
        /// <param name="storedProcedure">存储过程名称.</param>
        /// <param name="parameters">参数列表.</param>
        /// <returns>包含结果集的DataTable.</returns>
        protected internal DataTable FillDataTable(string schema, string storedProcedure, params object[] parameters)
        {
            return FillDataTable(schema, storedProcedure, PackageParameters(parameters));
        }

        /// <summary>
        /// 自定义的实体集合可以调用.不能用该方法填充实体.
        /// </summary>
        /// <param name="schema">See <see cref="IEntity.Schema"/>.</param>
        /// <param name="storedProcedure">存储过程名称.</param>
        /// <param name="parameters">参数列表.</param>
        /// <returns>包含结果集的DataTable.</returns>
        protected internal DataTable FillDataTable(string schema, string storedProcedure, rbParameters parameters)
        {
            rbDataRequest request = this.CreateRequest();

            request.Parameters = parameters;
            request.Schema = schema;
            request.QueryText = storedProcedure;
            request.QueryType = rbQueryType.StoredProcedure;

            rbDataProvider provider = new rbDataProvider();
            rbDataResponse response = provider.FillDataTable(request, this.rb.Connection.ProviderSignature);

            return response.Table;
        }

        /// <summary>
        /// 自定义的实体集合可以调用.不能用该方法填充实体.
        /// </summary>
        /// <param name="catalog">"Northwind"就是例子. 请参阅<see cref="IEntity.Catalog"/>.</param>
        /// <param name="schema">"dbo" 就是例子. 请参阅<see cref="IEntity.Schema"/>.</param>
        /// <param name="storedProcedure">存储过程名称.</param>
        /// <returns>包含结果集的DataTable.</returns>
        protected internal DataTable FillDataTable(string catalog, string schema, string storedProcedure)
        {
            return FillDataTable(catalog, schema, storedProcedure, null as rbParameters);
        }

        /// <summary>
        /// 自定义的实体集合可以调用.不能用该方法填充实体.
        /// </summary>
        /// <param name="catalog">"Northwind"就是例子. 请参阅<see cref="IEntity.Catalog"/>.</param>
        /// <param name="schema">"dbo" 就是例子. 请参阅<see cref="IEntity.Schema"/>.</param>
        /// <param name="storedProcedure">存储过程名称.</param>
        /// <param name="parameters">参数列表.</param>
        /// <returns>包含结果集的DataTable.</returns>
        protected internal DataTable FillDataTable(string catalog, string schema, string storedProcedure, params object[] parameters)
        {
            return FillDataTable(catalog, schema, storedProcedure, PackageParameters(parameters));
        }

        /// <summary>
        /// 自定义的实体集合可以调用.不能用该方法填充实体.
        /// </summary>
        /// <param name="catalog">"Northwind"就是例子. 请参阅<see cref="IEntity.Catalog"/>.</param>
        /// <param name="schema">"dbo" 就是例子. 请参阅<see cref="IEntity.Schema"/>.</param>
        /// <param name="storedProcedure">存储过程名称.</param>
        /// <param name="parameters">参数列表.</param>
        /// <returns>包含结果集的DataTable.</returns>
        protected internal DataTable FillDataTable(string catalog, string schema, string storedProcedure, rbParameters parameters)
        {
            rbDataRequest request = this.CreateRequest();

            request.Parameters = parameters;
            request.Catalog = catalog;
            request.Schema = schema;
            request.QueryText = storedProcedure;
            request.QueryType = rbQueryType.StoredProcedure;

            rbDataProvider provider = new rbDataProvider();
            rbDataResponse response = provider.FillDataTable(request, this.rb.Connection.ProviderSignature);

            return response.Table;
        }

        #endregion

        #region FillDataSet

        /// <summary>
        /// 自定义的实体集合可以调用.不能用该方法填充实体.
        /// </summary>
        /// <example>
        /// <code>
        /// public partial class EmployeesCollection : esEmployeesCollection
        /// {
        ///     public DataSet CustomFillDataSet()
        ///     {
        ///			string sqlText = String.Empty;
        /// 
        ///         sqlText = "SELECT * ";
        ///         sqlText += "FROM [Employees] ";
        ///         sqlText += "WHERE [LastName] = {0}";
        /// 
        ///         return this.FillDataSet(rbQueryType.Text, sqlText, "Doe");
        ///     }
        /// }
        /// </code>
        /// </example>
        /// <param name="queryType">请参阅<see cref="rbQueryType"/>.</param>
        /// <param name="query">SQL语句或存储过程名称.</param>
        /// <returns>包含结果集的DataSet.</returns>
        protected internal DataSet FillDataSet(rbQueryType queryType, string query)
        {
            return FillDataSet(queryType, query, null as rbParameters);
        }

        /// <summary>
        /// 自定义的实体集合可以调用.不能用该方法填充实体.
        /// </summary>
        /// <param name="queryType">请参阅<see cref="rbQueryType"/>.</param>
        /// <param name="query">SQL语句或存储过程名称.</param>
        /// <param name="parameters">参数列表.</param>
        /// <returns>包含结果集的DataSet.</returns>
        protected internal DataSet FillDataSet(rbQueryType queryType, string query, params object[] parameters)
        {
            return FillDataSet(queryType, query, PackageParameters(parameters));
        }

        /// <summary>
        /// 自定义的实体集合可以调用.不能用该方法填充实体.
        /// </summary>
        /// <param name="queryType">请参阅<see cref="rbQueryType"/>.</param>
        /// <param name="query">SQL语句或存储过程名称.</param>
        /// <param name="parms">参数列表.</param>
        /// <returns>包含结果集的DataSet.</returns>
        protected internal DataSet FillDataSet(rbQueryType queryType, string query, rbParameters parms)
        {
            rbDataRequest request = this.CreateRequest();

            request.Parameters = parms;
            request.QueryText = query;
            request.QueryType = queryType;

            rbDataProvider provider = new rbDataProvider();
            //rbDataResponse response = provider.FillDataTable(request, this.rb.Connection.ProviderSignature);
            rbDataResponse response = provider.FillDataSet(request, this.rb.Connection.ProviderSignature);
            return response.DataSet;
        }

        /// <summary>
        /// 自定义的实体集合可以调用.不能用该方法填充实体.
        /// </summary>
        /// <example>
        /// <code>
        /// public partial class EmployeesCollection : esEmployeesCollection
        /// {
        ///     public DataSet CustomFillDataSet()
        ///     {
        ///			return this.FillDataSet(this.rb.Schema, "MyStoredProc");
        ///     }
        /// }
        /// </code>
        /// </example>
        /// <param name="schema">See <see cref="IEntity.Schema"/>.</param>
        /// <param name="storedProcedure">存储过程名称.</param>
        /// <returns>包含结果集的DataSet.</returns>
        protected internal DataSet FillDataSet(string schema, string storedProcedure)
        {
            return FillDataSet(schema, storedProcedure, null as rbParameters);
        }

        /// <summary>
        /// 自定义的实体集合可以调用.不能用该方法填充实体.
        /// </summary>
        /// <param name="schema">See <see cref="IEntity.Schema"/>.</param>
        /// <param name="storedProcedure">存储过程名称.</param>
        /// <param name="parameters">参数列表.</param>
        /// <returns>包含结果集的DataSet.</returns>
        protected internal DataSet FillDataSet(string schema, string storedProcedure, params object[] parameters)
        {
            return FillDataSet(schema, storedProcedure, PackageParameters(parameters));
        }

        /// <summary>
        /// 自定义的实体集合可以调用.不能用该方法填充实体.
        /// </summary>
        /// <param name="schema">See <see cref="IEntity.Schema"/>.</param>
        /// <param name="storedProcedure">存储过程名称.</param>
        /// <param name="parameters">参数列表.</param>
        /// <returns>包含结果集的DataSet.</returns>
        protected internal DataSet FillDataSet(string schema, string storedProcedure, rbParameters parameters)
        {
            rbDataRequest request = this.CreateRequest();

            request.Parameters = parameters;
            request.Schema = schema;
            request.QueryText = storedProcedure;
            request.QueryType = rbQueryType.StoredProcedure;

            rbDataProvider provider = new rbDataProvider();
            rbDataResponse response = provider.FillDataSet(request, this.rb.Connection.ProviderSignature);

            return response.DataSet;
        }

        /// <summary>
        /// 自定义的实体集合可以调用.不能用该方法填充实体.
        /// </summary>
        /// <param name="catalog">"Northwind"就是例子. 请参阅<see cref="IEntity.Catalog"/>.</param>
        /// <param name="schema">"dbo" 就是例子. 请参阅<see cref="IEntity.Schema"/>.</param>
        /// <param name="storedProcedure">存储过程名称.</param>
        /// <returns>包含结果集的DataSet.</returns>
        protected internal DataSet FillDataSet(string catalog, string schema, string storedProcedure)
        {
            return FillDataSet(catalog, schema, storedProcedure, null as rbParameters);
        }

        /// <summary>
        /// 自定义的实体集合可以调用.不能用该方法填充实体.
        /// </summary>
        /// <param name="catalog">"Northwind"就是例子. 请参阅<see cref="IEntity.Catalog"/>.</param>
        /// <param name="schema">"dbo" 就是例子. 请参阅<see cref="IEntity.Schema"/>.</param>
        /// <param name="storedProcedure">存储过程名称.</param>
        /// <param name="parameters">参数列表.</param>
        /// <returns>包含结果集的DataSet.</returns>
        protected internal DataSet FillDataSet(string catalog, string schema, string storedProcedure, params object[] parameters)
        {
            return FillDataSet(catalog, schema, storedProcedure, PackageParameters(parameters));
        }

        /// <summary>
        /// 自定义的实体集合可以调用.不能用该方法填充实体.
        /// </summary>
        /// <param name="catalog">"Northwind"就是例子. 请参阅<see cref="IEntity.Catalog"/>.</param>
        /// <param name="schema">"dbo" 就是例子. 请参阅<see cref="IEntity.Schema"/>.</param>
        /// <param name="storedProcedure">存储过程名称.</param>
        /// <param name="parameters">参数列表.</param>
        /// <returns>包含结果集的DataSet.</returns>
        protected internal DataSet FillDataSet(string catalog, string schema, string storedProcedure, rbParameters parameters)
        {
            rbDataRequest request = this.CreateRequest();

            request.Parameters = parameters;
            request.Catalog = catalog;
            request.Schema = schema;
            request.QueryText = storedProcedure;
            request.QueryType = rbQueryType.StoredProcedure;

            rbDataProvider provider = new rbDataProvider();
            rbDataResponse response = provider.FillDataSet(request, this.rb.Connection.ProviderSignature);

            return response.DataSet;
        }

        #endregion

        #endregion

        #region ListChanged Event Logic

        /// <summary>
        /// 当rbEntityCollection数据发生改变时调用.
        /// </summary>
        public virtual event ListChangedEventHandler ListChanged
        {
            add
            {
                listChangedEventHandlerCount++;
                onListChangedEvent += value;

                if (entities.RaiseListChangedEvents == false)
                {
                    entities.RaiseListChangedEvents = true;
                }
            }
            remove
            {
                listChangedEventHandlerCount = Math.Max(0, --listChangedEventHandlerCount);
                onListChangedEvent -= value;

                if (listChangedEventHandlerCount == 0)
                {
                    entities.RaiseListChangedEvents = false;
                }
            }
        }

        private void OnListChanged(object sender, ListChangedEventArgs e)
        {
            ListChangedEventHandler handler = onListChangedEvent;
            if (handler != null)
            {
                handler(this, e);
            }
        }

        [NonSerialized]
#if (!WindowsCE)
        [IgnoreDataMember]
#endif
        private ListChangedEventHandler onListChangedEvent;

        #endregion

        #region rbUpdateViewEventHandler

        internal virtual event rbUpdateViewEventHandler UpdateViewNotification
        {
            add
            {
                updateViewNotification += value;
            }
            remove
            {
                updateViewNotification -= value;
            }
        }

        internal override void OnUpdateViewNotification(object sender, ListChangedType changeType, rbEntity obj)
        {
            rbUpdateViewEventHandler handler = updateViewNotification;
            if (handler != null)
            {
                handler(this, changeType, obj);
            }
        }

        [NonSerialized]
#if (!WindowsCE)
        [IgnoreDataMember]
#endif
        private rbUpdateViewEventHandler updateViewNotification;

#endregion 

        #region ICommittable Members

        bool ICommittable.Commit()
        {
            AcceptChanges();
            return true;
        }

        #endregion

        /// <summary>
        /// 用于层次化代码.
        /// </summary>
        /// 
        [NonSerialized, XmlIgnore]
        public Dictionary<string, object> fks = new Dictionary<string, object>();

        [NonSerialized]
        private int saveNestingCount = 0;

        [NonSerialized]
#if (!WindowsCE)
        [IgnoreDataMember]
#endif
        private int listChangedEventHandlerCount;


        internal BindingList<T> entities = new BindingList<T>();
        internal BindingList<T> entitiesFilterBackup;

        internal IList<T> deletedEntities;

#if (!WindowsCE)
        [NonSerialized]
        internal IQueryable<T> currentFilter;
#endif

        [NonSerialized]
        private T objectCreator = new T();

        [NonSerialized]
        static internal rbExtendedPropertyAttribute extendedPropertyAttribute = new rbExtendedPropertyAttribute();

        [NonSerialized]
        static internal rbHierarchicalPropertyAttribute hierarchicalPropertyAttribute = new rbHierarchicalPropertyAttribute();
    }
}
